﻿//*** Guidance generated code ***//
using System;
using System.Collections.Generic;
using System.Linq;

using Newtonsoft.Json;

namespace $safeprojectname$
{
    [JsonObject]
    public class MetaDataMessage
    {
        #region members

        private IList<MDAttribute> _attributes;

        #endregion members

        public string EntityName { get; set; }

        public string EntityType { get; set; }

        public bool CanRead { get; set; }

        public bool CanEdit { get; set; }

        [JsonIgnore]
        public IList<string> IgnoredProperties { get; set; }

        public IList<MDAttribute> Attributes
        {
            get { return _attributes ?? (_attributes = new List<MDAttribute>()); }
            protected set { _attributes = value; }
        }

        #region Clone

        public virtual MetaDataMessage Clone()
        {
            var clone = MemberwiseClone() as MetaDataMessage;
            clone.Attributes = Attributes
                .OrderBy(i => !i.Name.IsEqual(Constants.Common.ID))
                .ThenBy(i => i.IsAdditional)
                .ThenBy(i => i.IsArray)
                .ThenBy(i => i.Name)
                .Select(i => i.Clone())
                .ToList();

            clone.IgnoredProperties = IgnoredProperties.ToList();
            return clone;
        }

        #endregion Clone

        public virtual MDAttribute GetAttribute(string name)
        {
            return Attributes.FirstOrDefault(a => a.Name.IsEqual(name));
        }

        public override string ToString()
        {
            return EntityName + " (" + EntityType + ")";
        }
    }

    [JsonObject]
    public class MDAttribute
    {
        #region members

        private IList<IMDValidationRule> _validationRules;

        #endregion members

        public string Name { get; set; }
        public string DisplayName { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string PersistenceName { get; set; }

        public string DataType { get { return Type.Name; } }
        [JsonIgnore]
        public Type Type { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string SubType { get; set; }

        [JsonIgnore]
        public bool IsNullable { get; set; }
        [JsonIgnore]
        public bool IsAdditional { get; set; }
        public bool IsArray { get; set; }

        [JsonIgnore]
        public bool IsEntityReference { get; set; }

        [JsonIgnore]
        public bool HasSubtype { get { return SubType.IsNotEmpty(); } }

        public bool CanQuery { get; set; }
        public bool CanRead { get; set; }
        public bool CanEdit { get; set; }

        [JsonIgnore]
        public int? ProfileId { get; set; }

        [JsonIgnore]
        public MappingDescription MappingInfo { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public IList<MDAttribute> Attributes { get; set; }

        public IList<IMDValidationRule> ValidationRules
        {
            get { return _validationRules ?? (_validationRules = new List<IMDValidationRule>()); }
            protected set { _validationRules = value; }
        }

        #region Clone

        public virtual MDAttribute Clone()
        {
            var clone = MemberwiseClone() as MDAttribute;
            if (Attributes.IsNotEmpty())
            {
                clone.Attributes = Attributes
                    .OrderBy(i => !i.Name.IsEqual(Constants.Common.ID))
                    .ThenBy(i => i.IsAdditional)
                    .ThenBy(i => i.IsArray)
                    .ThenBy(i => i.Name)
                    .Select(i => i.Clone())
                    .ToList();
            }
            clone.ValidationRules = ValidationRules.Select(i => i.Clone()).ToList();

            return clone;
        }

        #endregion Clone

        public virtual MDAttribute GetAttribute(string name)
        {
            return Attributes.FirstOrDefault(a => a.Name.IsEqual(name));
        }

        public override string ToString()
        {
            return Name + " (" + DataType + ")";
        }
    }

    [JsonObject]
    public interface IMDValidationRule
    {
        string Type { get; set; }

        IMDValidationRule Clone();
    }

    [JsonObject]
    public class MDStringRule : IMDValidationRule
    {
        private string _type = "length";

        public string Type
        {
            get { return _type; }
            set { _type = value; }
        }

        public bool IsRequired { get; set; }

        public int? MinLength { get; set; }

        public int MaxLength { get; set; }

        #region Clone

        IMDValidationRule IMDValidationRule.Clone()
        {
            return Clone();
        }

        public virtual MDStringRule Clone()
        {
            var clone = MemberwiseClone() as MDStringRule;
            return clone;
        }

        #endregion Clone
    }

    [JsonObject]
    public class MDMandatoryRule : IMDValidationRule
    {
        private string _type = "mandatory";

        public string Type
        {
            get { return _type; }
            set { _type = value; }
        }

        public bool IsRequired { get; set; }

        #region Clone

        IMDValidationRule IMDValidationRule.Clone()
        {
            return Clone();
        }

        public virtual MDMandatoryRule Clone()
        {
            var clone = MemberwiseClone() as MDMandatoryRule;
            return clone;
        }

        #endregion Clone
    }

    [JsonObject]
    public class MDValueTypeRule<TValueType> : IMDValidationRule
        where TValueType : struct, IComparable<TValueType>
    {
        private string _type = "range";

        public string Type
        {
            get { return _type; }
            set { _type = value; }
        }

        public bool IsRequired { get; set; }

        public TValueType MinValue { get; set; }

        public TValueType MaxValue { get; set; }

        #region Clone

        IMDValidationRule IMDValidationRule.Clone()
        {
            return Clone();
        }

        public virtual MDValueTypeRule<TValueType> Clone()
        {
            var clone = MemberwiseClone() as MDValueTypeRule<TValueType>;
            return clone;
        }

        #endregion Clone
    }

    [JsonObject]
    public class MDMultipleRule : IMDValidationRule
    {
        private string _type = "multiple";

        public string Type
        {
            get { return _type; }
            set { _type = value; }
        }

        public string OverProperty { get; set; }

        public object PropertyValue { get; set; }

        public bool IsMultiple { get; set; }

        #region Clone

        IMDValidationRule IMDValidationRule.Clone()
        {
            return Clone();
        }

        public virtual MDMultipleRule Clone()
        {
            var clone = MemberwiseClone() as MDMultipleRule;
            return clone;
        }

        #endregion Clone
    }
}